home *** CD-ROM | disk | FTP | other *** search
- /*
- File: CardSpecific.c
-
- Contains: Card-dependent portion of the PC Card Sample Client
- In this case, a sample driver for the IBM OEM Ethernet PC Card.
-
- Written by: Dave Falkenburg with lots of helpful code from:
- James Blair, Mark D. Rustad, and Richard W. Mincher.
-
- Copyright © 1995 by Apple Computer, Inc., all rights reserved.
-
- Change History (most recent first):
-
- <0> 11/28/95 DRF first code.
- */
-
-
- #include "PCCardClient.h"
-
- // function prototypes
-
- static OSErr GetEthernetHardwareAddress(PCCardClientGlobalsRec * globals,PCCardPerSocketState * socketState,UInt16 socket);
- static OSErr GetPacketMemorySize(PCCardClientGlobalsRec * /* globals */,PCCardPerSocketState * /* socketState */,UInt16 socket);
-
-
-
- Boolean
- IsThisMyCard(PCCardClientGlobalsRec * /* globals */, UInt16 socket)
- {
- GetTuplePB getTuplePB;
- OSErr err;
- Boolean result = false;
-
- // Get the CISTPL_MANFID from the card’s CIS and compare it to our known IDs
-
- getTuplePB.socket = socket;
- getTuplePB.attributes = 0;
- getTuplePB.tupleOffset = 0;
- getTuplePB.desiredTuple = CISTPL_MANFID;
-
- err = CSGetFirstTuple(&getTuplePB);
- if (err == noErr)
- {
- getTuplePB.u.TupleDataPB.tupleDataMax = MAX_TUPLE_SIZE;
-
- err = CSGetTupleData(&getTuplePB);
- if (err == noErr)
- {
- UInt16 manfID = getTuplePB.u.TupleDataPB.tupleData.manufID.TPLMID_MANF;
- UInt16 card = getTuplePB.u.TupleDataPB.tupleData.manufID.TPLMID_CARD;
-
- // If we match, set the result to true
-
- result = ((manfID == kMyTPLMID_MANF) && (card == kMyTPLMID_CARD));
- }
- }
-
- if (result)
- IfDebugStr("\pIsThisMyCard: Card is mine");
- else
- IfDebugStr("\pIsThisMyCard: Not my card");
-
- return result;
- }
-
-
- OSErr
- ConfigureMyCard(PCCardClientGlobalsRec * globals,PCCardPerSocketState * socketState, UInt16 socket)
- {
- ReqModRelWindowPB wPB;
- GetModRequestConfigInfoPB configPB;
- OSErr result;
-
- IfDebugStr("\pConfigureMyCard");
-
- // Before we do anything, get our Ethernet hardware address
-
- result = GetEthernetHardwareAddress(globals,socketState,socket);
- if (result != noErr)
- {
- IfDebugStr("\pGetEthernetHardwareAddress failed");
- return result;
- }
-
-
- // Get the size of our memory buffers
-
- result = GetPacketMemorySize(globals,socketState,socket);
- if (result != noErr)
- {
- IfDebugStr("\pGetPacketMemorySize failed");
- return result;
- }
-
-
- // Allocate our Memory window, through which we will access our packet buffers
- // (we use a 300ns window, with a 16-bit datapath)
-
- wPB.clientHandle = globals->clientHandle;
- wPB.socket = socket;
- wPB.attributes = kCSEnableWindow | kCSMemoryWindow | kCS16BitDataPath | kCSAccessSpeedValid;
- wPB.base = 0;
- wPB.size = 0;
- wPB.accessSpeed = (kCSExtAccSpeedMant1pt0 << 3) | kCSExtAccSpeedExp100ns;
- result = CSRequestWindow(&wPB);
-
- if (result != noErr)
- {
- IfDebugStr("\pCSRequestWindow for Memory Window failed");
- return result;
- }
-
- socketState->memWindowHandle = wPB.windowHandle;
- socketState->memBase = (void *) wPB.base;
-
-
- // Allocate our I/O window
-
- // NOTE: Unlike memory windows, the I/O window will only “work” once we’ve told the card
- // to listen to I/O cycles. Requesting an I/O window only programs the PC Card
- // controller chip to generate I/O cycles. The PC Card itself must be activated
- // later via a call to RequestConfiguration.
-
- wPB.clientHandle = globals->clientHandle;
- wPB.socket = socket;
- wPB.attributes = kCSEnableWindow | kCSIOWindow;
- wPB.base = 0;
- wPB.size = 0;
- result = CSRequestWindow(&wPB);
-
- if (result != noErr)
- {
- IfDebugStr("\pCSRequestWindow for I/O Window failed...");
- return result;
- }
-
- socketState->ioWindowHandle = wPB.windowHandle;
- socketState->ioBase = (STNICReg *) wPB.base;
-
-
- // Lock-in the configuration for our PC Card by calling RequestConfiguration
- //
- // This serves several purposes:
- // 1) It tells Card Services that we are taking over management of the card
- // 2) It tells the PC Card that it should start responding to I/O cycles
- // 3) Keeps the Finder from telling the user that there is no software for
- // for the card.
-
- // Before we can request a configuration, be sure to get the previous configuration
-
- configPB.clientHandle = globals->clientHandle;
- configPB.socket = socket;
- result = CSGetConfigurationInfo(&configPB);
-
- if (result != noErr)
- {
- IfDebugStr("\pCSGetConfigurationInfo failed");
- return result;
- }
-
-
- // Set the new configuration via RequestConfiguration
-
- configPB.clientHandle = globals->clientHandle;
- configPB.attributes |= kCSValidClient | kCSTurnOnInUse /* | kCSEnableIREQs */;
- configPB.intType = kCSMemory_And_IO_Interface;
- configPB.configBase = 0x20000;
- configPB.status = 0x20; // I/O is 8 bit
- configPB.copy = 0;
- configPB.configIndex = 0x41; // Level Interrupts; Configuration #1
- configPB.present = kCSOptionRegisterPresent | kCSStatusRegisterPresent | kCSCopyRegisterPresent;
-
- result = CSRequestConfiguration(&configPB);
-
- if (result != noErr)
- {
- IfDebugStr("\pCSRequestConfiguration failed");
- return result;
- }
-
- // With all that PC Card housekeeping out of the way, go ahead and
- // initialize our card-specific hardware
-
-
- ///////////////////////////////
- //
- // INITIALIZE HARDWARE HERE!
- //
- ///////////////////////////////
-
-
- return noErr;
- }
-
-
- OSErr
- UnconfigureMyCard(PCCardClientGlobalsRec * globals,PCCardPerSocketState * socketState, UInt16 socket)
- {
- ReqModRelWindowPB wPB;
- ReleaseConfigurationPB configPB;
- OSErr result;
-
- IfDebugStr("\pUnconfigureMyCard");
-
- configPB.clientHandle = globals->clientHandle;
- configPB.socket = socket;
- result = CSReleaseConfiguration(&configPB);
- if (result != noErr)
- {
- IfDebugStr("\pCouldn't release configuration");
- }
-
- wPB.clientHandle = globals->clientHandle;
- wPB.windowHandle = socketState->ioWindowHandle;
- result = CSReleaseWindow(&wPB);
- if (result != noErr)
- {
- IfDebugStr("\pCouldn't release ioWindow");
- }
-
- wPB.clientHandle = globals->clientHandle;
- wPB.windowHandle = socketState->memWindowHandle;
- result = CSReleaseWindow(&wPB);
- if (result != noErr)
- {
- IfDebugStr("\pCouldn't release memWindow");
- }
-
- return noErr;
- }
-
-
- void
- MyCardInterruptHandler(PCCardClientGlobalsRec * /* globals */,PCCardPerSocketState * /* socketState */,UInt16 /* socket */)
- {
-
- /////////////////////////////////////////
- //
- // HANDLE YOUR CARD INTERRUPT HERE
- //
- /////////////////////////////////////////
-
- }
-
-
-
-
-
- static OSErr
- GetEthernetHardwareAddress(PCCardClientGlobalsRec * globals,PCCardPerSocketState * socketState,UInt16 socket)
- {
- ReqModRelWindowPB wPB;
- unsigned char * p;
- unsigned char i;
- OSErr result;
-
- // Before we do anything, go ahead and obtain our ethernet address by reading it
- // out of attribute memory.
-
- wPB.clientHandle = globals->clientHandle;
- wPB.socket = socket;
- wPB.attributes = kCSEnableWindow | kCSAttributeWindow;
- wPB.base = 0;
- wPB.size = 0;
- result = CSRequestWindow(&wPB);
-
- if (result != noErr)
- {
- IfDebugStr("\pCSRequestWindow for attribute memory failed");
- return result;
- }
-
- // For this card, the ethernet hardware address is stored at 0xFF0 bytes
- // into attrbute memory.
- //
- // Remember that attribute memory only exists in EVEN addresses, and
- // that is why we skip ahead two bytes at a time.
-
- p = (unsigned char *)(wPB.base) + 0xFF0;
- for(i=0; i < 6; i++, p+=2)
- {
- socketState->ethernetAddress[i] = *p;
- }
-
- result = CSReleaseWindow(&wPB);
- if (result != noErr)
- {
- IfDebugStr("\pCSReleaseWindow for attribute memory failed");
- return result;
- }
-
- return noErr;
- }
-
-
- static OSErr
- GetPacketMemorySize(PCCardClientGlobalsRec * /* globals */,PCCardPerSocketState * /* socketState */,UInt16 socket)
- {
- GetTuplePB getTuplePB;
- OSErr result;
-
- // Figure how much SRAM is available and what speed it is.
-
- getTuplePB.socket = socket;
- getTuplePB.attributes = 0;
- getTuplePB.tupleOffset = 0;
- getTuplePB.desiredTuple = CISTPL_DEVICE;
- result = CSGetFirstTuple(&getTuplePB);
- if (result != noErr)
- {
- IfDebugStr("\pCSGetFirstTuple failed.");
- return result;
- }
-
- getTuplePB.u.TupleDataPB.tupleDataMax = MAX_TUPLE_SIZE;
- result = CSGetTupleData(&getTuplePB);
- if (result != noErr)
- {
- IfDebugStr("\pCSGetTupleData failed.");
- return result;
- }
-
- switch(getTuplePB.u.TupleDataPB.tupleData.tupleData[1])
- {
- case 0x0a: // 16K SRAM buffer in common memory
- IfDebugStr("\p16K card");
- // gPageStart = 0x40;
- // gPageStop = 0x80;
- break;
-
- case 0x3a: // 64K SRAM buffer in common memory
- IfDebugStr("\p64K card");
- // gPageStart = 0x00;
- // gPageStop = 0xFF;
- break;
-
- default:
- IfDebugStr("\pUnknown SRAM configuration.");
- result = kCSGeneralFailureErr;
- break;
- }
-
- return result;
- }
-